from lib.config.index import service_config
import asyncio


class TaskManager:
    def __init__(self) -> None:
        self.__inits = []
        self.__daemons = []
        self.__tasks = []
        self.__is_debug = service_config.is_debug()
        self.__loading = 0

    def append_init(self, init_func):
        self.__inits.append(init_func)

    def append_daemon(self, daemon_func):
        self.__daemons.append(daemon_func)

    def append_task(self, task_init):
        self.__tasks.append(task_init)

    def print_service_info(self, type, service):
        print(f"load {type} > ", service.__service__, ":", service.__description__)

    def run_Main(self):
        co_daemons = self.load_all_daemons()
        co_tasks = self.start_all_tasks()
        loop = asyncio.get_event_loop()
        all_groups = asyncio.gather(*co_daemons, *co_tasks)
        loop.run_until_complete(all_groups)

    def start_all_inits(self):
        for i in self.__inits:
            i.init()
            i.run()

        for d in self.__daemons:
            d.init()

        for t in self.__tasks:
            t.init()

        if self.__is_debug:
            print("inits load finished")
            print("-----------------------------------------------------")

    def load_all_daemons(self):
        co_daemons = []
        for daemon in self.__daemons:
            if service_config.is_debug():
                self.print_service_info("daemon -->", daemon)
            co_daemons.append(daemon.run())
        return co_daemons

    def start_all_tasks(self):
        co_tasks = []
        for task in self.__tasks:
            if service_config.is_debug():
                print("asyncio loop exec task: ", task)

            if self.__loading == 0:
                self.print_service_info("task", task)
            co_tasks.append(task.run())
            # 加载完毕
            if self.__loading == 0:
                self.__loading = 1
        return co_tasks


class ServiceManager:
    def __init__(self) -> None:
        self.__task_m = TaskManager()
        self.__services = service_config.get_enabled_startup_services()
        self.__root = "services"
        self.__is_debug = service_config.is_debug()

    def get_service_script(self, service_name):
        return f"{self.__root}.{service_name}"

    def load_startup_services(self):
        if self.__is_debug:
            print("current startup services: ", self.__services)

        for service in self.__services:
            self.load(service)
        self.__task_m.start_all_inits()
        self.__task_m.run_Main()

    def load(self, service):
        name = service["name"]
        type = service["type"]

        module = __import__(self.get_service_script(name))
        m_attr = getattr(module, name)

        if type == "init":
            # print(service)
            self.__task_m.append_init(m_attr)

        if type == "daemon":
            # print(service)
            self.__task_m.append_daemon(m_attr)

        if type == "task":
            # print(service)
            self.__task_m.append_task(m_attr)


if __name__ == "__main__":
    service_manager = ServiceManager()
    service_manager.load_startup_services()
